/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.diplomka.webapp.research;

import cz.fi.muni.diplomka.common.enumeration.BuildingType;
import cz.fi.muni.diplomka.common.enumeration.ResearchType;
import cz.fi.muni.diplomka.common.enumeration.ResourceType;
import cz.muni.fi.diplomka.servicelayer.dto.BuildingInCity;
import cz.muni.fi.diplomka.servicelayer.dto.City;
import cz.muni.fi.diplomka.servicelayer.dto.Research;
import cz.muni.fi.diplomka.servicelayer.dto.ResearchInProgress;
import cz.muni.fi.diplomka.servicelayer.gamelogic.manager.CityBuildingManager;
import cz.muni.fi.diplomka.servicelayer.gamelogic.manager.CityManager;
import cz.muni.fi.diplomka.servicelayer.gamelogic.manager.ResearchManager;
import cz.muni.fi.diplomka.servicelayer.gamelogic.manager.CityResourcesManager;
import cz.muni.fi.diplomka.servicelayer.gamelogic.managerimpl.CityBuildingManagerImpl;
import cz.muni.fi.diplomka.servicelayer.gamelogic.managerimpl.CityManagerImpl;
import cz.muni.fi.diplomka.servicelayer.gamelogic.managerimpl.ResearchManagerImpl;
import cz.muni.fi.diplomka.servicelayer.gamelogic.managerimpl.CityResourcesManagerImpl;
import cz.muni.fi.diplomka.servicelayer.xmlconvertors.ResearchConvertor;
import cz.muni.fi.diplomka.webapp.layout.LinkPanel;
import cz.muni.fi.diplomka.webapp.resource.ResourcesPanel;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.PropertyModel;

/**
 *
 * @author Jakub Kutil
 */
public class ResearchPage extends WebPage {

    private String selectedCity = "";
    private List<String> cities;
    private CityManager cityManager = new CityManagerImpl();
    private ResearchManager cityResearchManager = new ResearchManagerImpl();
    private CityResourcesManager cityResourcesManager = new CityResourcesManagerImpl();
    private CityBuildingManager cityBuildingManager = new CityBuildingManagerImpl();

    public ResearchPage(PageParameters parameters) {
        final Long id;

        add(new FeedbackPanel("feedback"));

        if (parameters.containsKey("id")) {
            id = Long.parseLong(parameters.getString("id"));
            PageParameters p = new PageParameters();
            p.add("id", parameters.getString("id"));
            add(new LinkPanel("linkPanel", p));

            cities = new ArrayList<>();
            for (City c : cityManager.getCitiesByPlayerId(id)) {
                cities.add(c.getName());
            }
            if (parameters.containsKey("cityName")) {
                selectedCity = parameters.getString("cityName");
            }

            if (selectedCity.equals("")) {
                selectedCity = cities.get(0).toString();
            }

            p.add("cityName", selectedCity);
            
            add(new ResourcesPanel("resourcesPanel", p));
            
            final DropDownChoice<String> city = new DropDownChoice<>("city",
                    new PropertyModel<String>(this, "selectedCity"), cities);



            Form<?> form = new Form<Void>("form") {
                @Override
                protected void onSubmit() {
                    selectedCity = cities.get(Integer.parseInt(city.getValue()));
                    PageParameters pageParameters = new PageParameters();
                    pageParameters.add("id", id.toString());
                    pageParameters.add("cityName", selectedCity);
                    setResponsePage(ResearchPage.class, pageParameters);
                }
            };

            add(form);
            form.add(city);
            add(new Label("cityName", selectedCity));

            List<Research> list = new ArrayList<>();
            List<ResearchInProgress> inProgress = cityResearchManager.getAllResearchesInProgressOfPlayer(id);
            List<Research> researched = cityResearchManager.getAllFinishedResearchesOfPlayer(id);

            final ResearchConvertor researchConvertor = new ResearchConvertor();
            for (ResearchType researchType : ResearchType.values()) {
                Research r = researchConvertor.getResearchFromXML(researchType.toString());
                ResearchInProgress rip = new ResearchInProgress();
                rip.setResearchType(r.getResearchType());
                if (!researched.contains(r) && !inProgress.contains(rip)) {
                    list.add(r);
                }
            }

            ListView researches = new ListView("researches", list) {
                @Override
                protected void populateItem(ListItem item) {
                    final Research research = (Research) item.getModelObject();
                    item.add(new Label("name", research.getResearchType().toString()));
                    item.add(new Label("priceFood", research.getPriceFood() + ""));
                    item.add(new Label("priceGold", research.getPriceGold() + ""));
                    item.add(new Label("priceStone", research.getPriceStone() + ""));
                    item.add(new Label("priceTime", research.getPriceStone() + ""));

                    String effects = "";
                    for (Map.Entry<String, Integer> entry : research.getEffects().entrySet()) {
                        effects += entry.getKey() + " " + ((entry.getValue() > 0) ? "+" : "") + entry.getValue() + " ";
                    }
                    item.add(new Label("effects", effects));

                    String requires = "";
                    for (Map.Entry<BuildingType, Integer> entry : research.getRequires().entrySet()) {
                        requires += entry.getKey().toString() + " " + entry.getValue() + " ";
                    }
                    item.add(new Label("requires", requires));

                    Form<?> start = new Form<Void>("start") {
                        @Override
                        protected void onSubmit() {
                            PageParameters pageParameters = new PageParameters();
                            pageParameters.add("id", id.toString());
                            pageParameters.add("name", research.getResearchType().toString());

                            boolean ok = true;
                            boolean requirements = false;
                            Long cityId = cityManager.getCityByName(selectedCity).getId();
                            if (research.getPriceFood() > cityResourcesManager.getResourceCount(cityId, ResourceType.Food)) {
                                ok = false;
                                error("You do not have enough food to start research.");
                            }
                            if (research.getPriceGold() > cityResourcesManager.getResourceCount(cityId, ResourceType.Gold)) {
                                ok = false;
                                error("You do not have enough gold to start research.");
                            }
                            if (research.getPriceStone() > cityResourcesManager.getResourceCount(cityId, ResourceType.Stone)) {
                                ok = false;
                                error("You do not have enough stone to start research.");
                            }
                            for (Map.Entry<BuildingType, Integer> entry : research.getRequires().entrySet()) {
                                for (BuildingInCity building : cityBuildingManager.getAllBuildingsInCityOfType(cityId, entry.getKey())) {
                                    if (building.getLevel() >= entry.getValue()) {
                                        requirements = true;
                                        break;
                                    }
                                }
                            }
                            if (ok == true && requirements == true) {

                                cityResourcesManager.lowerResource(cityId, ResourceType.Food, research.getPriceFood());
                                cityResourcesManager.lowerResource(cityId, ResourceType.Gold, research.getPriceGold());
                                cityResourcesManager.lowerResource(cityId, ResourceType.Stone, research.getPriceStone());

                                ResearchInProgress researchInProgress = new ResearchInProgress();
                                researchInProgress.setPlayerId(id);
                                researchInProgress.setResearchType(research.getResearchType());
                                researchInProgress.setTimeOfFinish(new Timestamp((long) (System.currentTimeMillis() + 1000 * 60 * research.getPriceTime())));
                                cityResearchManager.startResearch(researchInProgress);
                                setResponsePage(ResearchPage.class, pageParameters);
                            }
                            if (requirements != true) {
                                error("Requirements to start research are not met.");
                            }

                        }
                    };
                    item.add(start);
                }
            };
            add(researches);

            ListView researchedView = new ListView("researched", researched) {
                @Override
                protected void populateItem(ListItem item) {
                    final Research research = (Research) item.getModelObject();
                    item.add(new Label("name", research.getResearchType().toString()));

                    String effects = "";
                    for (Map.Entry<String, Integer> entry : researchConvertor.getResearchFromXML(research.getResearchType().toString()).getEffects().entrySet()) {
                        effects += entry.getKey() + " " + ((entry.getValue() > 0) ? "+" : "") + entry.getValue() + " ";
                    }
                    item.add(new Label("effects", effects));
                }
            };
            add(researchedView);

            ListView inProgressView = new ListView("inProgress", inProgress) {
                @Override
                protected void populateItem(ListItem item) {
                    final ResearchInProgress researchInProgress = (ResearchInProgress) item.getModelObject();
                    item.add(new Label("name", researchInProgress.getResearchType().toString()));
                    String effects = "";
                    for (Map.Entry<String, Integer> entry : researchConvertor.getResearchFromXML(researchInProgress.getResearchType().toString()).getEffects().entrySet()) {
                        effects += entry.getKey() + " " + ((entry.getValue() > 0) ? "+" : "") + entry.getValue() + " ";
                    }
                    item.add(new Label("effects", effects));
                    item.add(new Label("timeOfFinish", researchInProgress.getTimeOfFinish().toString()));
                }
            };
            add(inProgressView);
        }

    }
}
